import java.time.Clock;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.MonthDay;
import java.time.Period;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;

/**
 * <b>Java 8</b>
 * <p>
 * 新日期操作
 * </p>
 * <p>
 * 来源: https://mp.weixin.qq.com/s/2pLcZupdUXPqve6gFJZ0HQ
 *
 * @Author Rocky Wong
 * @Date 2020/1/15 0015 10:33
 */
public class Java8DateTime {

    /**
     * <b>获取今天的日期</b>
     * <p>
     * Java 8 中的 LocalDate 用于表示当天日期。和java.util.Date不同，它只有日期，不包含时间。当你仅需要表示日期时就用这个类。
     * </p>
     *
     * @param
     * @return
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 10:35
     */
    public void toDay() {
        LocalDate today = LocalDate.now();
        System.out.println("今天的日期:" + today);
    }

    /**
     * <b>获取年/月/日</b>
     * <p>
     * </p>
     *
     * @param
     * @return
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 10:49
     */
    public void ymd() {
        LocalDate today = LocalDate.now();
        int year = today.getYear();
        int month = today.getMonthValue();
        int day = today.getDayOfMonth();

        System.out.println("year:" + year);
        System.out.println("month:" + month);
        System.out.println("day:" + day);
    }

    /**
     * <b>创建</b>
     * <p>
     * </p>
     *
     * @param
     * @return
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 10:50
     */
    public void create() {
        LocalDate date = LocalDate.of(2020, 1, 15);
        System.out.println("自定义日期:" + date);
    }

    /**
     * <b>日期比较</b>
     * <p>
     * </p>
     *
     * @param
     * @return
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 10:52
     */
    public void dateEqual() {
        LocalDate date1 = LocalDate.now();

        LocalDate date2 = LocalDate.of(2020, 1, 15);

        if (date1.equals(date2)) {
            System.out.println("相等");
        } else {
            System.out.println("不等");
        }
    }

    /**
     * <b>比较月日</b>
     * <p>
     * </p>
     *
     * @param
     * @return
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 10:53
     */
    public void birthday() {
        LocalDate date1 = LocalDate.now();

        LocalDate date2 = LocalDate.of(2020, 9, 19);
        MonthDay birthday = MonthDay.of(date2.getMonth(), date2.getDayOfMonth());
        MonthDay currentMonthDay = MonthDay.from(date1);

        if (currentMonthDay.equals(birthday)) {
            System.out.println("今天是你的生日");
        } else {
            System.out.println("今天不是你的生日");
        }
    }

    public void datePlus() {
        LocalDate today = LocalDate.now();
        System.out.println("今天的日期为:" + today);
        LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
        System.out.println("一周后的日期为:" + nextWeek);

        LocalDate previousYear = today.minus(1, ChronoUnit.YEARS);
        System.out.println("一年前的日期 : " + previousYear);

        LocalDate nextYear = today.plus(1, ChronoUnit.YEARS);
        System.out.println("一年后的日期:" + nextYear);
    }

    /**
     * <b>当前时间</b>
     * <p>
     * 只包含时间信息，没有日期
     * </p>
     *
     * @param
     * @return
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 10:54
     */
    public void time() {
        LocalTime time = LocalTime.now();
        System.out.println("获取当前的时间:" + time);
    }

    /**
     * <b>时间加</b>
     * <p>
     * </p>
     *
     * @param
     * @return
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 10:55
     */
    public void timePlus() {
        LocalTime time = LocalTime.now();
        LocalTime newTime = time.plusHours(5);
        System.out.println("5个小时后的时间为:" + newTime);
    }

    /**
     * <b>System.currentTimeInMillis</b>
     * <p>
     * </p>
     *
     * @param
     * @return
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 10:58
     */
    public void currentTimeInMillis() {
        // Returns the current time based on your system clock and set to UTC.
        Clock clock = Clock.systemUTC();
        System.out.println("Clock : " + clock.millis());

        // Returns time based on system clock zone
        Clock defaultClock = Clock.systemDefaultZone();
        System.out.println("Clock : " + defaultClock.millis());

        // Instant类有一个静态工厂方法now()会返回当前的时间戳
        Instant timestamp = Instant.now();
        System.out.println("What is value of this instant " + timestamp.toEpochMilli());
    }

    /**
     * <b>日期时间</b>
     * <p>
     * 默认市区为UTC(世界标准时间), 与中国时间相差8小时
     * </p>
     *
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 10:59
     *
     * @param
     * @return
     */
    public void dateTime() {
        Instant instant = Instant.now();        
        System.out.println("UTC: " + instant);        
        Instant instant2 = Instant.now(Clock.systemUTC());        
        System.out.println("UTC: " + instant2);        
        Instant instant3 = Clock.systemUTC().instant();        
        System.out.println("UTC: " + instant3);        
        Instant now = Instant.now().plusMillis(TimeUnit.HOURS.toMillis(8));        
        System.out.println("北京时间: " + now);                
        Instant now2 = Instant.now(Clock.system(ZoneId.of("Etc/GMT+8")));        
        System.out.println("东8区时间: " + now);
        // UTC: 2019-07-24T02:11:32.744Z
        // UTC: 2019-07-24T02:11:32.890Z
        // UTC: 2019-07-24T02:11:32.890Z
        // 北京时间: 2019-07-24T10:11:32.890Z
        // 东8区时间: 2019-07-24T10:11:32.890Z
    }

    /**
     * <b>日期大小比较</b>
     * <p>
     * </p>
     *
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 10:59
     *
     * @param
     * @return
     */
    public void comparator() {
        LocalDate today = LocalDate.now();

        LocalDate tomorrow = LocalDate.of(2020, 1, 15);
        if (tomorrow.isAfter(today)) {
            System.out.println("之后的日期:" + tomorrow);
        }

        LocalDate yesterday = today.minus(1, ChronoUnit.DAYS);
        if (yesterday.isBefore(today)) {
            System.out.println("之前的日期:" + yesterday);
        }
    }

    /**
     * <b>时区</b>
     * <p>
     * </p>
     *
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 11:00
     *
     * @param
     * @return
     */
    public void zone() {
        // Date and time with timezone in Java 8
        ZoneId america = ZoneId.of("Asia/Shanghai");
        LocalDateTime localtDateAndTime = LocalDateTime.now();
        ZonedDateTime dateAndTimeInNewYork  = ZonedDateTime.of(localtDateAndTime, america );
        System.out.println("Current date and time in a particular timezone : " + dateAndTimeInNewYork);
    }

    /** 
     * <b>TODO</b>
     * <p>
     *     与 MonthDay检查重复事件的例子相似，YearMonth是另一个组合类，用于表示信用卡到期日、FD到期日、期货期权到期日等。还可以用这个类得到 当月共有多少天，YearMonth实例的lengthOfMonth()方法可以返回当月的天数，在判断2月有28天还是29天时非常有用。
     * </p>
     *
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 11:04
     *
     * @param 
     * @return 
     */
    public void expire(){
        YearMonth currentYearMonth = YearMonth.now();
        System.out.printf("Days in month year %s: %d%n", currentYearMonth, currentYearMonth.lengthOfMonth());
        YearMonth creditCardExpiry = YearMonth.of(2020, Month.FEBRUARY);
        System.out.printf("Your credit card expires on %s %n", creditCardExpiry);
        // 单月多少天
        creditCardExpiry.get(ChronoField.DAY_OF_MONTH);
    }

    /** 
     * <b>检查闰年</b>
     * <p>
     * </p>
     *
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 11:05
     *
     * @param 
     * @return 
     */
    public void leap() {
        LocalDate today = LocalDate.now();
        if(today.isLeapYear()){
            System.out.println("This year is Leap year");
        }else {
            System.out.println("2018 is not a Leap year");
        }
    }

    /**
     * <b>两个日期之间的天数和月数</b>
     * <p>
     * </p>
     *
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 11:07
     *
     * @param
     * @return
     */
    public void between() {
        LocalDate today = LocalDate.now();

        LocalDate java8Release = LocalDate.of(2020, 1, 14);

        Period periodToNextJavaRelease = Period.between(today, java8Release);
        System.out.println("Months left between today and Java 8 release : "
                + periodToNextJavaRelease.getMonths() );
    }

    /**
     * <b>格式化日期</b>
     * <p>
     * </p>
     *
     * @Author Rocky Wong
     * @Date 2020/1/15 0015 11:08
     *
     * @param
     * @return
     */
    public void formatter(){
        String dayAfterTommorrow = "20200115";
        LocalDate formatted = LocalDate.parse(dayAfterTommorrow,
                DateTimeFormatter.BASIC_ISO_DATE);
        System.out.println(dayAfterTommorrow+"  格式化后的日期为:  "+formatted);

        LocalDateTime date = LocalDateTime.now();

        DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        //日期转字符串
        String str = date.format(format1);

        System.out.println("日期转换为字符串:"+str);

        DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        //字符串转日期
        LocalDate date2 = LocalDate.parse(str,format2);
        System.out.println("日期类型:"+date2);
    }
}
